package com.maiji.cloud.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Maps;
import com.maiji.cloud.entities.login.AppUser;
import com.maiji.cloud.entities.login.UserInfo;
import com.maiji.cloud.mapper.AppUserMapper;
import com.maiji.cloud.microservice.CapitalMainMService;
import com.maiji.cloud.request.BaseDataReqDto;
import com.maiji.cloud.request.login.XCXBindTelReqData;
import com.maiji.cloud.request.login.XCXLoginReqData;
import com.maiji.cloud.response.BaseDataResDto;
import com.maiji.cloud.response.Status;
import com.maiji.cloud.response.login.XCXLoginResData;
import com.maiji.cloud.service.AppUserService;
import com.maiji.cloud.service.UserService;
import com.maiji.cloud.utils.AES;
import com.maiji.cloud.utils.RedisUtil;
import com.maiji.cloud.utils.UUID_MD5;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/wx/")
public class WXController {

    private static final Logger logger = LoggerFactory.getLogger(WXController.class);
    @Value("${wx.appid}")
    private String appid;
    @Value("${wx.secret}")
    private String secret;
    @Value("${wx.url}")
    private String url;
    @Autowired
    private AppUserService appUserService;
    @Autowired
    private UserService userService;
    @Autowired
    private CapitalMainMService capitalMainMService;
    @Autowired
    private RedisTemplate<String, Object> maiji1RedisTemplate;
    @Autowired
    private RedisTemplate<String, Object> maiji2RedisTemplate;
    @Autowired
	private AppUserMapper appUserMapper;

    @ApiOperation(value = "登录")
    @PostMapping("/login")
    public BaseDataResDto<XCXLoginResData> logon (@RequestBody BaseDataReqDto<XCXLoginReqData> baseDataReqDto) {
        XCXLoginReqData data = baseDataReqDto.getData();
        String jsCode = data.getJsCode();
        if (StringUtil.isBlank(jsCode)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        Map<String, String> param = new HashMap<>();
        param.put("appid", appid);
        param.put("secret", secret);
        param.put("js_code", jsCode);
        param.put("grant_type", "authorization_code");
        url += "?appid={appid}&secret={secret}&js_code={js_code}&grant_type={grant_type}";
        logger.info("WXController.wx.login ===>> param: " + JSON.toJSONString(param));
//        JSONObject jsonObject = JSON.parseObject(new RestTemplate().getForObject(url, String.class, param));
        JSONObject jsonObject = JSON.parseObject(new RestTemplate().getForObject(
                "https://api.weixin.qq.com/sns/jscode2session?appid=wxda96e55a954ddae4&secret=bcbc8087160a4b7fdc05cdfb0e7c85dd&js_code="
                        +jsCode  + "&grant_type=authorization_code", String.class));
        logger.info("WXController.wx.login ===>> jsonObject: " + jsonObject.toJSONString());
        Integer errcode = (Integer) jsonObject.get("errcode");
        if (errcode != null && errcode != 0) return new BaseDataResDto<>(Status.ERROR);
        XCXLoginResData wxLoginResData = new XCXLoginResData()
                .setSession_key((String) jsonObject.get("session_key"))
                .setOpenid((String) jsonObject.get("openid"));
        return new BaseDataResDto<XCXLoginResData>(Status.SUCCESS).setData(wxLoginResData);
    }

    @ApiOperation(value = "微信小程序绑定手机号")
    @PostMapping("/bindTel")
    public BaseDataResDto<String> bindTel (@RequestBody BaseDataReqDto<XCXBindTelReqData> baseDataReqDto) {
        XCXBindTelReqData data = baseDataReqDto.getData();
        String openIdWX = data.getOpenId();
        if (StringUtil.isBlank(openIdWX)) return new BaseDataResDto<>(Status
                .USER_WORNING_INFO.setMessage("绑定手机号失败，请重新打开小程序后再试"));
        String phoneNumber;
        if (StringUtil.isNotBlank(data.getTel())) {
            phoneNumber = data.getTel();
            if (! appUserService.checkCode(phoneNumber, data.getCode())) return new BaseDataResDto(Status.IDENTIFYCODEINVALID);
        } else {
            // 1.解析加密数据
            String encryptedData = data.getEncryptedData();
            String sessionKey = data.getSessionKey();
            String iv = data.getIv();
            cn.hutool.json.JSONObject userencryptedData = AES.wxDecrypt(encryptedData, sessionKey, iv);
            phoneNumber = (String) userencryptedData.get("phoneNumber");
        }
        if (StringUtil.isBlank(phoneNumber) || ! phoneNumber.matches("^[1][0-9]{10}$"))
            return new BaseDataResDto(Status.PARAMETERERROR);
        // 验证手机号是否已注册
        EntityWrapper<AppUser> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("tel", phoneNumber);
        entityWrapper.or();
        entityWrapper.eq("open_id_wx", openIdWX);
        AppUser appUser = appUserService.selectOne(entityWrapper);
        if (appUser == null) {  // 未注册
            String pwd = UUID_MD5.randomPwd();
            String tokenWx = UUID_MD5.md5Str(phoneNumber + pwd.toUpperCase() + System.currentTimeMillis());
            appUser = new AppUser().setUuId(UUID_MD5.getUUID()).setOpenIdWx(data.getOpenId()).setPwd(UUID_MD5.md5Str(pwd))
                    .setTokenWx(tokenWx).setTokenStatusWx(1).setRegDate(new Date()).setTel(phoneNumber).setIsBan(0);
            if(StringUtils.isNotBlank(data.getDistributionNum())) {
                String pidUserId = checkDistributionNum(data.getDistributionNum());
                if(StringUtils.isBlank(pidUserId)) return new BaseDataResDto(Status.PARAMETERERROR);
                appUserService.logonPidCount(appUser.setPid(pidUserId));
            }
            if (! appUserService.insert(appUser)) return new BaseDataResDto<>(Status.APPUSERINSERTFAILED);
            if (! capitalMainMService.createCapitalMain(appUser.getUuId()))
                return new BaseDataResDto<>(Status.ERROR.setMessage("创建用户资金账户失败！"));
        } else {  // 已注册
            if (appUser.getIsBan() == 1) return new BaseDataResDto(Status.USER_WORNING_INFO.setMessage("该账户已被禁止登录"));
            String tokenWxNew = UUID_MD5.md5Str(phoneNumber + appUser.getPwd().toUpperCase() + System.currentTimeMillis());
            appUser.setOpenIdWx(data.getOpenId()).setTel(phoneNumber).setTokenWx(tokenWxNew).setTokenStatusWx(1);
            if (! appUserService.updateById(appUser)) return new BaseDataResDto<>(Status.APPUSERINSERTFAILED);
        }
        //保存用户头像
        UserInfo userInfo = userService.selectOne(new EntityWrapper<UserInfo>().eq("user_id", appUser.getUuId()));
        if (userInfo == null) {
            userInfo = new UserInfo().setUuId(UUID_MD5.getUUID()).setUserId(appUser.getUuId()).setSex(data.getSex())
                    .setNickName(data.getNickName()).setHeadUrl(data.getHeadUrl()).setRegDate(new Date());
            if (! userService.insert(userInfo)) return new BaseDataResDto<>(Status.ERROR.setMessage("保存用户基本信息失败！"));
        } else {
            if (StringUtil.isBlank(userInfo.getNickName()) || userInfo.getNickName().startsWith("Maiji-")) userInfo.setNickName(data.getNickName());
            if (StringUtil.isBlank(userInfo.getHeadUrl())) userInfo.setNickName(data.getNickName());
            if (userInfo.getSex() == null) userInfo.setSex(data.getSex());
            if (! userService.updateById(userInfo)) return new BaseDataResDto<>(Status.ERROR.setMessage("保存用户基本信息失败！"));
        }
        RedisUtil.setObject(maiji1RedisTemplate, "maijiToken:" + appUser.getTokenWx(), appUser);
        if (maiji2RedisTemplate != null) RedisUtil.setObject(maiji2RedisTemplate, "maijiToken:" + appUser.getTokenWx(), appUser);
        return new BaseDataResDto<String>(Status.SUCCESS).setData(appUser.getTokenWx());
    }

    @ApiOperation(value = "小程序微信登录")
    @PostMapping("/openidLogin")
    public BaseDataResDto<String> openidLogin (@RequestBody BaseDataReqDto<String> baseDataReqDto) {
        String openIdWx = baseDataReqDto.getData();
        if (StringUtil.isBlank(openIdWx)) return new BaseDataResDto<>(Status.USER_WORNING_INFO.setMessage("登录失败，请重新打开小程序后再试"));
        AppUser appUser = appUserService.selectOne(new EntityWrapper<AppUser>().eq("open_id_wx", openIdWx));
        if (appUser == null) return new BaseDataResDto(Status.UNREGISTERED);
        if (appUser.getIsBan() == 1) return new BaseDataResDto(Status.USER_WORNING_INFO.setMessage("该账户已被禁止登录"));
        String tokenWxNew = UUID_MD5.md5Str(appUser.getTel() + appUser.getPwd().toUpperCase() + System.currentTimeMillis());
        appUser.setTokenWx(tokenWxNew).setTokenStatusWx(1);
        if (! appUserService.updateById(appUser)) return new BaseDataResDto<>(Status.APPUSERINSERTFAILED);
        RedisUtil.setObject(maiji1RedisTemplate, "maijiToken:" + appUser.getTokenWx(), appUser);
        if (maiji2RedisTemplate != null) RedisUtil.setObject(maiji2RedisTemplate, "maijiToken:" + appUser.getTokenWx(), appUser);
        return new BaseDataResDto<String>(Status.SUCCESS).setData(appUser.getTokenWx());
    }

    /**
	 * 根据分销码查看用户id并校验分销码是否正确
	 * @param distributionNum
	 * @return
	 */
	public String checkDistributionNum(String distributionNum) {
		if (StringUtil.isBlank(distributionNum)) return null;
		AppUser appUser = appUserMapper.selectOne(new AppUser().setDistributionNum(distributionNum));
		if(appUser != null) return appUser.getUuId();
		return null;
	}

    @PostMapping("/img_sec_check")
    public JSONObject img_sec_check (@RequestParam("files")  MultipartFile[] files,
                                     @RequestParam("content") String content) throws IOException {
        String appid = "wxda96e55a954ddae4";
        String secret = "bcbc8087160a4b7fdc05cdfb0e7c85dd";
        String url = "https://api.weixin.qq.com/cgi-bin/token?" +
                "grant_type=client_credential&appid="+appid+"&secret="+secret;
        JSONObject jsonObject = new RestTemplate().getForObject(url, JSONObject.class);
        System.out.println(jsonObject);
        String access_token = jsonObject.getString("access_token");

        String url2 = "https://api.weixin.qq.com/wxa/img_sec_check?access_token="+access_token;

        URLConnection connection = new URL("https://media.vipissy.com/models/jasmine-webb/cover/l.jpg").openConnection();
        InputStream inputStream = connection.getInputStream();
//        InputStream inputStream = file.getInputStream();
        byte[] bytes = new byte[inputStream.available()];
//        HashMap<Object, Object> map = Maps.newHashMap();
//        map.put("media", file);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        HttpEntity requestEntity = new HttpEntity(bytes, headers);
        JSONObject jsonObject1 = JSON.parseObject(new RestTemplate().postForObject(url2, requestEntity, String.class));
        System.out.println(jsonObject1);
        return jsonObject1;
    }
}
